package com.hb.trade.portal.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb.core.pojo.Attachment;
import com.hb.core.pojo.Attachments;
import com.hb.core.pojo.center.sys.entity.DistrictInfo;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.portal.dto.PortalAddrDTO;
import com.hb.core.pojo.portal.dto.PortalFileDTO;
import com.hb.core.pojo.portal.dto.PortalNewsDTO;
import com.hb.core.pojo.portal.entity.PortalFile;
import com.hb.core.pojo.portal.entity.PortalNews;
import com.hb.core.pojo.portal.vo.PortalAddrVo;
import com.hb.core.pojo.project.homepage.dto.AnnouncementsDTO;
import com.hb.core.pojo.project.portal.dto.PortalNoticeDTO;
import com.hb.core.pojo.project.section.dto.BidSectionCountDTO;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.trade.client.center.DictionaryClient;
import com.hb.trade.client.project.*;
import com.hb.trade.portal.service.PortalFileService;
import com.hb.trade.portal.service.PortalService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.fzzn.core.component.treebuilder.util.TreeUtil;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.util.MsgUtil;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 门户网站API控制器
 *
 * @author ljs
 * @date 2022-2-15 16:54:23
 */
@Slf4j
@Version(1.0)
@Api(tags = {"门户网站"})
@RequestMapping("/{version}")
@RestController
public class ApiPortalController {
    protected NoticeClient noticeClient;
    protected PortalNoticeClient portalNoticeClient;
    protected BidWinResultClient bidWinResultClient;
    protected BidOpeningHallClient bidOpeningHallClient;
    protected DictionaryClient dictionaryClient;
    protected SectionClient sectionClient;
    protected final AnnouncementsClient announcementsClient;
    protected final PortalService portalService;
    protected final PortalFileService portalFileService;
    protected final DealClient dealClient;
    private static String key = "8533ee9914d0cd455e112801e0af5dae";


    public ApiPortalController(PortalService portalService,
                               PortalFileService portalFileService,
                               NoticeClient noticeClient,
                               BidOpeningHallClient bidOpeningHallClient,
                               DictionaryClient dictionaryClient,
                               SectionClient sectionClient,
                               AnnouncementsClient announcementsClient,
                               PortalNoticeClient portalNoticeClient,
                               BidWinResultClient bidWinResultClient, DealClient dealClient) {
        this.portalService = portalService;
        this.noticeClient = noticeClient;
        this.portalFileService = portalFileService;
        this.bidWinResultClient = bidWinResultClient;
        this.bidOpeningHallClient = bidOpeningHallClient;
        this.dictionaryClient = dictionaryClient;
        this.sectionClient = sectionClient;
        this.announcementsClient = announcementsClient;
        this.portalNoticeClient = portalNoticeClient;
        this.dealClient = dealClient;
    }

    @ApiOperation(value = "公告列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "province", value = "省", dataTypeClass = String.class),
            @ApiImplicitParam(name = "city", value = "市", dataTypeClass = String.class),
            @ApiImplicitParam(name = "noticeType", value = "项目分类：1: 工程, 2: 货物, 3: 服务", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "projectModule", value = "公告类型 1 建设工程 2 政府采购 3 企业采购", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "noticeTitle", value = "公告标题", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "publishStartDate", value = "开始时间", dataTypeClass = Date.class),
            @ApiImplicitParam(name = "publishEndDate", value = "结束时间", dataTypeClass = Date.class),
            @ApiImplicitParam(name = "applyStatus", value = "发布状态（1：正在报名，2：已截止）", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "noticeNatureSign", value = "公告性质 1.招标公告 2.变更公告 3.结果公示", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "sortType", value = "公告性质 1.最近发布 2、按时间正序", dataTypeClass = Integer.class)
    })
    @PostMapping("/portal/noticeList")
    public ResponseDto noticeList(@RequestBody PortalNoticeDTO portalNoticeDTO) {
        if (portalNoticeDTO == null || portalNoticeDTO.getNoticeType() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        return ResultUtil.msg(portalNoticeClient.pagePortalNoticeList(portalNoticeDTO));
    }


    @ApiOperation(value = "相关公告", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "公告ID", dataTypeClass = String.class),
            @ApiImplicitParam(name = "sectionId", value = "标段ID", dataTypeClass = String.class),
            @ApiImplicitParam(name = "noticeNature", value = "公告性质 1.首次公告 2 变更公告 3.延期公告 4 补充 5 终止 6 再次 7 最高限价公告, 8 流标公示", dataTypeClass = Integer[].class)
    })
    @PostMapping("/portal/relatedNoticeList")
    public ResponseDto relatedNoticeList(@RequestBody PortalNoticeDTO portalNoticeDTO) {
        if (portalNoticeDTO == null || portalNoticeDTO.getProjectId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        return ResultUtil.msg(portalNoticeClient.listPortalNotice(portalNoticeDTO));
    }

    @ApiOperation(value = "公告详情", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "公告ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "noticeNatureSign", value = "公告类型标志：1.招标公告 2.变更公告 3.结果公示", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "queryType", value = "2 候选人公示", dataTypeClass = Integer.class)
    })
    @PostMapping("/portal/noticeDetail")
    public ResponseDto noticeDetail(@RequestBody PortalNoticeDTO portalNoticeDTO) {
        if (portalNoticeDTO == null || portalNoticeDTO.getId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        return ResultUtil.msg(portalNoticeClient.findNoticeById(portalNoticeDTO));
    }

    @ApiOperation(value = "新闻列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "noticeType", value = "新闻类型（1：综合新闻: 2：行业动态）", dataTypeClass = Integer.class)
    })
    @PostMapping("/portal/newsList")
    public ResponseDto newsList(@RequestBody PortalNewsDTO portalNewsDTO) {
        if (portalNewsDTO == null) {
            Message result = MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
            return ResultUtil.msg(result);
        }
        // 根据新闻类型查询新闻列表
        LambdaQueryWrapper<PortalNews> queryWrapper = new LambdaQueryWrapper<>();

        // 如果传入标题则根据标题进行搜索
        if (portalNewsDTO.getTitle() != null) {
            queryWrapper.like(PortalNews::getTitle, portalNewsDTO.getTitle());
        }
        if (portalNewsDTO.getNoticeType() != null) {
            queryWrapper.eq(PortalNews::getNoticeType, portalNewsDTO.getNoticeType());
        }
        if (portalNewsDTO.getStatus() != null) {
            queryWrapper.eq(PortalNews::getStatus, portalNewsDTO.getStatus());
        }
        queryWrapper.orderByDesc(PortalNews::getPublishTime);
//        queryWrapper.eq(PortalNews::getNoticeType, portalNewsDTO.getNoticeType());
        Page<PortalNews> portalNewsPage = portalService.page(portalNewsDTO.pages(), queryWrapper);

        Page<PortalNewsDTO> portalNewsDTOPage = new Page<>();
        List<PortalNewsDTO> records = new ArrayList<>();
        for (PortalNews news : portalNewsPage.getRecords()) {
            PortalNewsDTO newsDTO = news.to(PortalNewsDTO.class);
            if (!StringUtils.isEmpty(newsDTO.getContentText())) {
                newsDTO.setContentText(StripHT(newsDTO.getNoticeContent()));
            }
            // 日期格式化
            if (news.getPublishTime() != null) {
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                newsDTO.setPublishDate(news.getPublishTime().format(df));
            }
            records.add(newsDTO);
        }
        // 设置分页信息
        portalNewsDTOPage.setRecords(records);
        portalNewsDTOPage.setTotal(portalNewsPage.getTotal());
        portalNewsDTOPage.setPages(portalNewsPage.getPages());
        portalNewsDTOPage.setCurrent(portalNewsPage.getCurrent());
        Message result = MsgUtil.success(PageResult.get(portalNewsDTOPage));
        return ResultUtil.msg(result);
    }

    @ApiOperation(value = "新闻详情", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "公告ID", dataTypeClass = Long.class)
    })
    @PostMapping("/portal/newsDetail")
    public ResponseDto newsDetail(@RequestBody PortalNewsDTO portalNewsDTO) {
        if (portalNewsDTO == null || portalNewsDTO.getId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        PortalNews news = portalService.getById(portalNewsDTO.getId());
        PortalNewsDTO newsDTO = news.to(PortalNewsDTO.class);
        // 统计访问量
        Integer num = 0;
        if (news.getClickCount() != null) {
            num = news.getClickCount();
        }
        news.setClickCount(num + 1);
        portalService.updateById(news);
        // 日期格式化
        if (news.getPublishTime() != null) {
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            newsDTO.setPublishDate(news.getPublishTime().format(df));
        }
        return ResultUtil.msg(MsgUtil.success(newsDTO));
    }

    @ApiOperation(value = "新闻删除", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "公告ID", dataTypeClass = Long.class)
    })
    @PostMapping("/portal/newsDelete")
    public ResponseDto newsDelete(@RequestBody PortalNewsDTO portalNewsDTO) {
        if (portalNewsDTO == null || portalNewsDTO.getId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        boolean remove = portalService.removeById(portalNewsDTO.getId());
        Message res = remove ? MsgUtil.success(MsgEnum.SUCCESS) : MsgUtil.fail(MsgEnum.FAILURE.msg());
        return ResultUtil.msg(res);
    }

    @ApiOperation(value = "新闻修改", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "公告ID", dataTypeClass = Long.class)
    })
    @PostMapping("/portal/newsEdit")
    public ResponseDto newsEdit(@RequestBody PortalNewsDTO portalNewsDTO) {
        if (portalNewsDTO == null || portalNewsDTO.getId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        boolean update = portalService.updateById(portalNewsDTO);
        Message res = update ? MsgUtil.success(MsgEnum.SUCCESS) : MsgUtil.fail(MsgEnum.FAILURE.msg());
        return ResultUtil.msg(res);
    }

    @ApiOperation(value = "保存新闻", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "title", value = "新闻标题", dataTypeClass = String.class),
            @ApiImplicitParam(name = "content", value = "新闻正文", dataTypeClass = String.class),
            @ApiImplicitParam(name = "noticeType", value = "新闻类型（1：综合新闻: 2：行业动态）", dataTypeClass = Integer.class)
    })
    @PostMapping("/portal/newsSave")
    public ResponseDto newsSave(@RequestBody PortalNewsDTO portalNewsDTO) {
        if (portalNewsDTO == null || portalNewsDTO.getTitle() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        PortalNews news = portalNewsDTO.to(PortalNews.class);
        news.setPublishTime(LocalDateTime.now());
        news.setCreateTime(LocalDateTime.now());
        news.setClickCount(0);
        news.buildBaseData(1);
        news.setPublishTime(LocalDateTime.now());
        boolean result = portalService.save(news);
        Message res = result ? MsgUtil.success(MsgEnum.SUCCESS) : MsgUtil.fail(MsgEnum.FAILURE.msg());
        return ResultUtil.msg(res);
    }

    @ApiOperation(value = "资料列表（下载中心）", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "publishTime", value = "发布时间", dataTypeClass = Date.class),
            @ApiImplicitParam(name = "fileName", value = "文件名", dataTypeClass = String.class),
    })
    @PostMapping("/portal/fileList")
    public ResponseDto fileList(@RequestBody PortalFileDTO portalFileDTO) {
        Page<PortalFileDTO> portalFileDTOPage = portalFileService.pagePortalFile(portalFileDTO);
        for (PortalFileDTO fileDTO : portalFileDTOPage.getRecords()) {
            if (fileDTO.getCreateTime() != null) {
                fileDTO.setPublishDate(fileDTO.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }
        return ResultUtil.msg(MsgUtil.success(PageResult.get(portalFileDTOPage)));
    }

    @ApiOperation(value = "统计下载量", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataTypeClass = Long.class)
    })
    @PostMapping("/portal/fileCount")
    public ResponseDto fileCount(@RequestBody PortalFileDTO portalFileDTO) {
        if (portalFileDTO == null || portalFileDTO.getId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        //下载次数+1
        PortalFile portalFile = portalFileService.getById(portalFileDTO.getId());
        if (portalFile != null) {
            Integer num = portalFile.getDownloadCount();
            if (num == null) {
                num = 0;
            }
            portalFile.setDownloadCount(num + 1);
        }
        boolean result = portalFileService.updateById(portalFile);
        Message res = result ? MsgUtil.success(MsgEnum.SUCCESS) : MsgUtil.fail(MsgEnum.FAILURE.msg());
        return ResultUtil.msg(res);
    }

    @ApiOperation(value = "保存资料列表（下载中心）", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileId", value = "文件ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "publishTime", value = "发布时间", dataTypeClass = Date.class),
            @ApiImplicitParam(name = "fileName", value = "文件名", dataTypeClass = String.class),
    })
    @PostMapping("/portal/fileSave")
    public ResponseDto fileSave(@RequestBody PortalFileDTO portalFileDTO) {
        if (portalFileDTO == null || portalFileDTO.getFileId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        PortalFile portalFile = portalFileDTO.to(PortalFile.class);
        portalFile.buildBaseData(1);
        boolean result = portalFileService.save(portalFile);
        Message res = result ? MsgUtil.success(MsgEnum.SUCCESS) : MsgUtil.fail(MsgEnum.FAILURE.msg());
        return ResultUtil.msg(res);
    }

    @ApiOperation(value = "开标大厅", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openBidTime", value = "今天的时间", dataTypeClass = Long.class)
    })
    @PostMapping("/portal/pageTodayOpeningSection")
    public ResponseDto pageTodayOpeningSection(@RequestBody BidSectionDTO bidSectionDTO) {
        Message result = bidOpeningHallClient.pageHomeTodayOpeningSection(bidSectionDTO);
        return ResultUtil.msg(result);
    }

    @ApiOperation(value = "中标金额、开标项目数等数据统计", httpMethod = "POST")
    @ApiImplicitParams({
    })
    @PostMapping("/portal/bidSectionCount")
    public ResponseDto bidSectionCount(@RequestBody BidSectionCountDTO bidSectionCountDTO) {
        return ResultUtil.msg(sectionClient.bidSectionCount(bidSectionCountDTO));
    }

    @ApiOperation(value = "重要通知/公告", httpMethod = "POST")
    @ApiImplicitParams({
    })
    @PostMapping("/portal/announcementsList")
    public ResponseDto announcementsList(@RequestBody AnnouncementsDTO announcementsDTO) {
        return ResultUtil.msg(announcementsClient.announcementsList(announcementsDTO));
    }

    @ApiOperation(value = "重要通知/公告 详情", httpMethod = "POST")
    @ApiImplicitParams({
    })
    @PostMapping("/portal/announcementsDetail")
    public ResponseDto announcementsDetail(@RequestBody AnnouncementsDTO announcementsDTO) {
        if (announcementsDTO == null || announcementsDTO.getId() == null) {
            return ResultUtil.msg(MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg()));
        }
        return ResultUtil.msg(announcementsClient.announcementsDetail(announcementsDTO));
    }

    @ApiOperation(value = "地区信息列表(返回树形结构)", notes = "地区信息列表(返回树形结构)", httpMethod = "POST")
    @PostMapping("/portal/treeDistricts")
    public ResponseDto treeDistricts() {
        Message<List<DistrictInfo>> list = dictionaryClient.listDistricts(new DistrictInfo());
        List<DistrictInfo> data = list.getData();
        JSONArray tree = TreeUtil.getTree(data, MapUtil.of("title", "disName"), false);
        return ResultUtil.msg(true, tree);
    }

    public static String StripHT(String strHtml) {
        String txtcontent = strHtml.replaceAll("</?[^>]+>", ""); //剔出<html>的标签
        txtcontent = txtcontent.replaceAll("<a>\\s*|\t|\r|\n</a>", "");//去除字符串中的空格,回车,换行符,制表符
        return txtcontent;
    }


    @PostMapping("/portalNotice/savePortalNotice")
    public void savePortalNotice(@RequestBody PortalNoticeDTO portalNoticeDTO) {
        portalNoticeClient.savePortalNotice(portalNoticeDTO);
    }

    @ApiOperation(value = "根据地区返回经纬度", notes = "调用高德地图API获取经纬度", httpMethod = "POST")
    @PostMapping("/portal/getLatAndLog")
    public ResponseDto<PortalAddrVo> getLatAndLog(@RequestBody PortalAddrDTO portalAddrDTO) {
        String address = portalAddrDTO.getAddress();
        if (address == null || address.equals("")) {
            address = "山东省济南市历下区银丰财富广场B座12层";

        }
        String geoURL = "https://restapi.amap.com/v3/geocode/geo?";
        StringBuffer str = new StringBuffer(geoURL);
        str.append("address=").append(address).append("&key=").append(key).append("&output=json");
        String location = HttpUtil.get(str.toString());
        //把String对象反序列化为Json对象
        JSONObject result = JSONUtil.parseObj(location);
        String status = result.getStr("status");
        if ((status.equals("1"))) {
            // 地址信息
            JSONArray info = result.getJSONArray("geocodes");
            JSONObject geocodes = info.getJSONObject(0);
            String local = geocodes.getStr("location");
            PortalAddrVo portalAddrVo = new PortalAddrVo();
            portalAddrVo.setLocation(local.split(","));
            return ResultUtil.msg(true, portalAddrVo);
        }

        return ResultUtil.fail(MsgEnum.FAILURE);
    }

}
